<?php
namespace app\index\controller;
use think\Controller;
error_reporting(E_ALL);
ini_set('display_errors', '1');
// 定义时区
ini_set('date.timezone','Asia/Shanghai');

class WeixinpayController  extends Controller{
	
	public function get_client_ip(){
		$ip = "unknown";
		if($_SERVER['REMOTE_ADDR'])
		{
		  $cip = $_SERVER['REMOTE_ADDR'];
		}else if(getenv("REMOTE_ADDR"))
		{
		   $cip = getenv("REMOTE_ADDR");
		}
		return $cip;
	}
    /**
     * 统一下单
     * @param  array $order 订单 必须包含支付所需要的参数 body(产品描述)、total_fee(订单金额)、out_trade_no(订单号)、product_id(产品id)、trade_type(类型：JSAPI，NATIVE，APP)
     */
    public function unifiedOrder($order){
        // 生成随机加密盐
        $nonce_str = $this->makeCode(24);
        $cip= $this->get_client_ip();
        // 获取配置项
        $config=array(
            'appid'=>config('wxpay.APPID'),
            'mch_id'=>config('wxpay.MCHID'),
            'nonce_str'=>$nonce_str,
            'spbill_create_ip'=>$cip,
            'notify_url'=>config('wxpay.NOTIFY_URL')
            );
        // 合并配置数据和订单数据
        $data=array_merge($order,$config);
		
        // 生成签名
        $sign=$this->makeSign($data);
        $data['sign']=$sign;
        $xml=$this->toXml($data);
        $url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';//接收xml数据的文件
        $header[] = "Content-type: text/xml";//定义content-type为xml,注意是数组
        $ch = curl_init ($url);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 兼容本地没有指定curl.cainfo路径的错误
        curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
        $response = curl_exec($ch);
        if(curl_errno($ch)){
            // 显示报错信息；终止继续执行
            die(curl_error($ch));
        }
        curl_close($ch);
        $result=$this->toArray($response);
        // 显示错误信息
        if ($result['return_code']=='FAIL') {
            die($result['return_msg']);
        }
        $result['sign']=$sign;
        $result['nonce_str']=$nonce_str;
        return $result;
    }

   
    
    /**
     * 输出xml字符
     * @throws WxPayException
    **/
    public function toXml($data){
        if(!is_array($data) || count($data) <= 0){
            throw new WxPayException("数组数据异常！");
        }
        $xml = "<xml>";
        foreach ($data as $key=>$val){
            if (is_numeric($val)){
                $xml.="<".$key.">".$val."</".$key.">";
            }else{
                $xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
            }
        }
        $xml.="</xml>";
        return $xml; 
    }

    /**
     * 生成签名
     * @return 签名，本函数不覆盖sign成员变量，如要设置签名需要调用SetSign方法赋值
     */
    public function makeSign($data){
        // 去空
        $data=array_filter($data);
        //签名步骤一：按字典序排序参数
        ksort($data);
        $string_a=http_build_query($data);
        $string_a=urldecode($string_a);
        //签名步骤二：在string后加入KEY
        $string_sign_temp=$string_a."&key=".config('wxpay.KEY');
        //签名步骤三：MD5加密
        $sign = md5($string_sign_temp);
        // 签名步骤四：所有字符转为大写
        $result=strtoupper($sign);
        return $result;
    }

    /**
     * 将xml转为array
     * @param  string $xml xml字符串
     * @return array       转换得到的数组
     */
    public function toArray($xml){   
        //禁止引用外部xml实体
        libxml_disable_entity_loader(true);
        $result= json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);        
        return $result;
    }

    /**
     * 生成随机串
     * @param $count 随机串个数
     */
    public function makeCode($count = 24)
    {
        $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
        $nonce_str = '';
        for ( $i = 0; $i < $count; $i++ ) {
            $nonce_str .= substr($chars, mt_rand(0, strlen($chars)-1), 1);
        }
		return $nonce_str;
    }

    /**
     * 获取jssdk需要用到的数据
     * @return array jssdk需要用到的数据
     */
    public function getParameters(){
    	$order_type =  input('order_type');
		$order_sn = input('order_sn');
		$total_fee = input('money');
        $total_fee = 0;
        if(input('money')){
        	$total_fee = input('money')*100;	
        }
		
		if($order_type==1){	//充值会费
			$result = add_pay_log(session('user_id'),0,input('money'),$order_type,$order_sn,2,1,input("WIDsubject"),0,now_time());
		}elseif($order_type==2){//订单
			//$result = add_pay_log(session('user_id'),$agent_id,$balance,$order_type,$order_sn,$pay_type,$state,$message,$order_id,$pay_time)
		}elseif($order_type==3){//充值小卡
			$result = add_pay_log(session('user_id'),0,input('money'),$order_type,$order_sn,2,1,input("WIDsubject"),0,now_time());
		}
		if(!$result){
			echo "支付失败！";
			exit;
		}
    	
        $order=array(
            'body'=> input('WIDbody'),// 商品描述（需要根据自己的业务修改）
            'total_fee'=> $total_fee,// 订单金额  以(分)为单位（需要根据自己的业务修改）
            'out_trade_no'=>$order_sn,// 订单号（需要根据自己的业务修改）
            'trade_type'=>'MWEB',// H5支付的交易类型为MWEB
            'scene_info'=>'{"h5_info": {"type":"Wap","wap_url":"http://www.bbwycn.com","wap_name":"支付"}}'//场景信息 必要参数
        );
		
        // 统一下单 获取prepay_id
        $unified_order=$this->unifiedOrder($order);
        // 获取当前时间戳
        $time=time();
        // 组合jssdk需要用到的数据
        $data=array(
            'appId'=>config('wxpay.APPID'), //appid
            'mweb_url'=>$unified_order['mweb_url'],//mweb_url为拉起微信支付收银台的中间页面，可通过访问该url来拉起微信客户端，完成支付,mweb_url的有效期为5分钟。
        );
        return $data;
    }

}

